﻿using System;
using System.Data;
using System.Configuration;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
using System.Diagnostics;
using System.IO;
using System.Text.RegularExpressions;
using System.Xml;

namespace CodeDemon.Models {
	public class ReviewModel : ReviewModelBase, CodeDemon.Models.ICodeDemonModel
	{
		public ReviewModel() : base() {
			DAO = new CodeDemonDb(ConfigurationManager.AppSettings["DSN"].ToString());
		}

		public CodeDemonDb DAO { get; set; }




		public void CreateReview( string Title, string Description, int DefectID, int ReviewUserID ) {
			// save the incomplete review
			Reviews newReview = new Reviews();
			newReview.Title = Title;
			newReview.Description = Description;
			newReview.DefectNumber = DefectID;
			newReview.ReviewCreatedTimeStamp = DateTime.Now;
			newReview.ReviewStatus = (from s in DAO.ReviewStatus where s.StatusName == "INCOMPLETE" select s).FirstOrDefault();
			newReview.Users = (from u in DAO.Users where u.UserID == ReviewUserID select u).FirstOrDefault();
			DAO.Reviews.InsertOnSubmit( newReview );
			DAO.SubmitChanges();
			CurrentReviewID = newReview.ReviewID;
		}

		public void InsertReviewFile( int reviewId, string UDiff, string filePath, int changeSet, string logMessage, string author, string changeAction, string stringChangeDate, int defectNumber, bool isBinary, int repositoryID ) {

			ReviewFiles newFile = new ReviewFiles();
			newFile.Author = author;
			newFile.ChangeAction = changeAction;
			newFile.ChangeDate = DateTime.Parse( stringChangeDate );
			newFile.EndRevision = changeSet;
			newFile.FilePath = filePath;
			newFile.IsBinary = isBinary;
			newFile.LogMessage = logMessage;
			newFile.FileDefectNumber = defectNumber;
			newFile.ReviewID = reviewId;
			newFile.StartRevision = changeSet - 1;
			newFile.UDiffText = UDiff;
			newFile.AddedToReviewTimestamp = DateTime.Now;
			newFile.RepositoryID = repositoryID;

			DAO.ReviewFiles.InsertOnSubmit( newFile );
			DAO.SubmitChanges();

		}

		public void InsertRevisionReview(int revision, int reviewID)
		{
			DAO.InsertSVNLogRevisionReview(revision, reviewID);
		}

		public void InsertReviewParticipant( int reviewID, int reviewUserID, bool isReviewer ) {
			var existing = (from parts in DAO.GetReviewParticipantsByReviewID(reviewID) where parts.ReviewUserID == CurrentReviewUserID select parts).Count();
			if( existing == 0) {
				DAO.InsertReviewParticipant( reviewID, reviewUserID, isReviewer );
				SendJoinAlert( reviewID, reviewUserID, isReviewer );
			}

		}

		public void InsertReviewLogEntry( int reviewId, string logMessage, int reviewFileID ) {
			DAO.AddReviewLogEntry( reviewId, logMessage, DateTime.Now, CurrentReviewUserID, reviewFileID );
		}

		public void InsertReviewLogEntry( int reviewId, string logMessage ) {
			DAO.AddReviewLogEntry( reviewId, logMessage, DateTime.Now, CurrentReviewUserID, null );
		}

		public void UpdateStatus( int reviewId, string newStatusName, int reviewUserID ) {
			Reviews updateReview = (from r in DAO.Reviews
									where r.ReviewID == reviewId
									select r).FirstOrDefault();

			ReviewStatus newStatus = (from s in DAO.ReviewStatus
									  where s.StatusName == newStatusName
									  select s).FirstOrDefault();
			DAO.UpdateReviewStatusByReviewID(reviewId, newStatus.ReviewStatusID);

			DAO.AddReviewLogEntry( reviewId, String.Format( "Review Status Updated to {0}", newStatusName ), DateTime.Now, reviewUserID, null );
		}

		public void UpdateApprovalStatus( int reviewId, int newStatusId ) {

			int partLister = (from parts in DAO.ReviewParticipants where parts.ReviewUserID == CurrentReviewUserID && parts.ReviewID == reviewId select parts).Count();
			if (partLister > 0) {
				//they are in the part list
				var newStatus = (from statusList in DAO.ReviewStatus where statusList.ReviewStatusID == newStatusId select statusList).FirstOrDefault();
				//TODO : Configuration to Allow/Disable "No-Comment Approvals" and "No-Comment Failures"
				if (newStatus.IsApprovalStatus == true) {
					InsertReviewLogEntry( reviewId, String.Format( "Review Approval Added" ) );
				}

				DAO.UpdateReviewParticipantStatus( CurrentReviewUserID, reviewId, newStatusId );
				InsertReviewLogEntry( reviewId, String.Format( "Review Participant Status Changed to {0}", newStatus.StatusName ) );

				int reviewersApprovedCount = (from statusList in DAO.GetReviewParticipantsByReviewID( reviewId )
											where statusList.IsApprovalStatus == true
											&& statusList.ParticipantIsReviewer == true
											select statusList).Count();

				int reviewersFailedCount = (from statusList in DAO.GetReviewParticipantsByReviewID( reviewId )
											where statusList.IsFinishedStatus == true 
											&& statusList.IsApprovalStatus == false
										    && statusList.ParticipantIsReviewer == true
										    select statusList).Count();

				int reviewersClosedCount = (from statusList in DAO.GetReviewParticipantsByReviewID( reviewId )
											where statusList.ParticipantIsReviewer == true
											&& statusList.IsFinishedStatus == true
											select statusList).Count();

				int reviewersCount = (from statusList in DAO.GetReviewParticipantsByReviewID( reviewId )
											where statusList.ParticipantIsReviewer == true
											select statusList).Count();

				bool reviewStatusHasChanged = false;
				string newStatusName = String.Empty;
				bool isApproved = false;
				bool isClosed = true;
				if (ConfigurationManager.AppSettings["InstantSuccess"] == "false" || ConfigurationManager.AppSettings["InstantSuccess"] == "no") {
					if (reviewersApprovedCount == reviewersCount) {
						// this review is approved : Congratulations!
						var newReviewStatus = (from statusList in DAO.ReviewStatus where statusList.StatusName == "APPROVED" select statusList).FirstOrDefault();
						DAO.UpdateReviewStatusByReviewID( reviewId, newStatus.ReviewStatusID );
						newStatusName = newReviewStatus.StatusName;
						isApproved = true;
						reviewStatusHasChanged = true;
					}
				} else {

					if (reviewersApprovedCount > 0) {
						// this review is approved : Congratulations!
						var newReviewStatus = (from statusList in DAO.ReviewStatus where statusList.StatusName == "APPROVED" select statusList).FirstOrDefault();
						DAO.UpdateReviewStatusByReviewID( reviewId, newStatus.ReviewStatusID );
						newStatusName = newReviewStatus.StatusName;
						isApproved = true;
						reviewStatusHasChanged = true;
					}
				}

				if (ConfigurationManager.AppSettings["InstantFailure"] == "false" || ConfigurationManager.AppSettings["InstantFailure"] == "no") {
					if (reviewersFailedCount >= reviewersApprovedCount && reviewersClosedCount == reviewersCount)
					{
						// this just found people who are Closed/NotApproved
						var newReviewStatus = (from statusList in DAO.ReviewStatus where statusList.StatusName == "NEEDSIMPROVEMENT" select statusList).FirstOrDefault();
						DAO.UpdateReviewStatusByReviewID(reviewId, newStatus.ReviewStatusID);
						newStatusName = newReviewStatus.StatusName;
						isClosed = true;
						reviewStatusHasChanged = true;
					}					
				} else {
					if (reviewersFailedCount > 0)
					{
						// InstantFailureMode is Disabled
						var newReviewStatus = (from statusList in DAO.ReviewStatus where statusList.StatusName == "NEEDSIMPROVEMENT" select statusList).FirstOrDefault();
						DAO.UpdateReviewStatusByReviewID(reviewId, newStatus.ReviewStatusID);
						newStatusName = newReviewStatus.StatusName;
						isClosed = true;
						reviewStatusHasChanged = true;
					}
				}
				if (reviewStatusHasChanged) {
					InsertReviewLogEntry( reviewId, String.Format( "Review Status Changed to {0}", newStatusName ) );
					SendStatusAlert( reviewId, newStatusName, isClosed, isApproved );
				}
			}
		}

		public void UpdateReviewDetails( int reviewId, string title, string description ) {
			DAO.UpdateReviewDetailsByReviewID( reviewId, title, description );
		}

		public void UpdateReviewUserSettings(bool create, bool status, bool comment, bool join, bool other_join, int reviewUserID)
		{
			Users updateUser = (from users in DAO.Users where users.UserID == reviewUserID select users).FirstOrDefault();
			updateUser.EnableCommentMail = comment;
			updateUser.EnableCreateMail = create;
			updateUser.EnableDeltaStatusMail = status;
			updateUser.EnableJoinMail = join;
			updateUser.EnableOtherReviewersMail = other_join;
			DAO.SubmitChanges();

		}

		public void InsertReviewComment(int reviewId, string commentText, int reviewUserId, short priority, int severityID)
		{
			ReviewComments newComment = new ReviewComments();
			newComment.CommentText = commentText;
			newComment.ReviewUserID = reviewUserId;
			newComment.ReviewID = reviewId;
			newComment.CommentTimestamp = DateTime.Now;
			newComment.SeverityID = severityID;
			newComment.Priority = priority;
			DAO.ReviewComments.InsertOnSubmit( newComment );
			try {
				DAO.SubmitChanges();
			}
			catch {
				throw;
			}
			InsertReviewLogEntry( reviewId, String.Format( "Added Review Comment" ) );
			var sev = (from sevs in DAO.Severity where sevs.SeverityID == severityID select sevs).FirstOrDefault();
			SendCommentAlert(reviewId, reviewUserId, commentText, sev.SeverityName, priority.ToString());
		}

		public void InsertReviewFileComment(int reviewFileId, string commentText, int lineNumber, int reviewUserId, short priority, int severityID)
		{
			ReviewFileComments newComment = new ReviewFileComments();
			newComment.CommentText = commentText;
			newComment.LineNumber = lineNumber;
			newComment.CommentTimestamp = DateTime.Now;
			newComment.ReviewUserID = reviewUserId;
			newComment.ReviewFileID = reviewFileId;
			newComment.SeverityID = severityID;
			newComment.Priority = priority;
			DAO.ReviewFileComments.InsertOnSubmit( newComment );
			try {
				DAO.SubmitChanges();
			}
			catch (System.Exception ex) {

				throw;
			}
			var thisReview = (from reviews in DAO.GetReviewByReviewFileID( reviewFileId ) select reviews).FirstOrDefault();
			if (reviewFileId == -1) {
			    InsertReviewLogEntry( thisReview.ReviewID.Value, String.Format( "Added File Comment on a file", lineNumber ), reviewFileId );
			} else {
			    InsertReviewLogEntry( thisReview.ReviewID.Value, String.Format( "Added File Comment on line {0}", lineNumber ), reviewFileId );
			}
			var sev = (from sevs in DAO.Severity where sevs.SeverityID == severityID select sevs).FirstOrDefault();
			var rev = (from files in DAO.ReviewFiles where files.ReviewFileID == reviewFileId select files).FirstOrDefault();
			SendCommentFileAlert(rev.ReviewID, reviewFileId, reviewUserId, newComment.ReviewFileCommentID, commentText, sev.SeverityName, priority.ToString());
		}


		public void InitialSVNLogLoad( string XmlPath ) {

			XDocument SvnLog = XDocument.Load(XmlPath);

			foreach (var rev in SvnLog.Descendants( "logentry" )) {
				string revision = rev.Attribute( "revision" ).Value;
				string author = rev.Element( "author" ).Value;
				string logMessage = rev.Element( "msg" ).Value;
				string date = rev.Element( "date" ).Value;
				string Xml = rev.ToString( SaveOptions.DisableFormatting );
				Regex findDefect = new Regex( ConfigurationManager.AppSettings["RegexForDefectInLogMessage"].ToString() );
				Match matcher = findDefect.Match( logMessage );
				string defectNumber = matcher.Groups["BUG_ID"].Value;

				if (defectNumber == String.Empty) {
					Regex emergencyBackup = new Regex( @"(?<BUG_ID>(\d)+)" );
					Match imatcher = emergencyBackup.Match( logMessage );
					defectNumber = imatcher.Groups["BUG_ID"].Value;
				}
				if (defectNumber != String.Empty) {
					try {
						DAO.InsertSVNLog( Int32.Parse( revision ), author.ToUpperInvariant(), DateTime.Parse( date ), logMessage, Xml, Int32.Parse( defectNumber ),1 );
					}
					catch (System.Exception ex) {
						throw;
					}
				}
				
			}
		}


		#region Mail & Alerting Methods
		public void SendCreateAlert( int reviewId ) {
			var review = (from reviews in DAO.GetReviewsById( reviewId ) select reviews).FirstOrDefault();
			var reviewOwner = (from users in DAO.GetUserByUserID( review.ReviewOwnerID ) select users).FirstOrDefault();

			if (reviewOwner.EnableCreateMail == true)
			{
				System.Net.Mail.SmtpClient client = new System.Net.Mail.SmtpClient(ConfigurationManager.AppSettings["SMTPServer"]);
				client.Send(ConfigurationManager.AppSettings["SendEmailFromAddress"], reviewOwner.ReviewUserEmail,
					//subject
							"CodeDemon - CR #" + review.ReviewID + " (" + review.StatusName + ") Created",
					//body
							"The CodeDemon review, CR #" + review.ReviewID + " which is currently in the status " + review.StatusName
							+ " been created." + Environment.NewLine + Environment.NewLine +
							"by user " + CurrentReviewUserEmail + " at " + DateTime.Now + Environment.NewLine + Environment.NewLine +
							ConfigurationManager.AppSettings["CodeDemonReviewLookupURL"] + reviewId);
			}
			this.CreateHook(reviewId, review.DefectNumber.Value);
		}

		public void SendJoinAlert( int reviewId, int reviewUserId, bool asReviewer ) {
			var review = (from reviews in DAO.GetReviewsById( reviewId ) select reviews).FirstOrDefault();
			var partList = from parts in DAO.GetReviewParticipantsByReviewID( reviewId ) where parts.EnableOtherReviewersMail == true && parts.ReviewUserID != reviewUserId select parts;
			var reviewOwner = (from users in DAO.GetUserByUserID(review.ReviewOwnerID) select users).FirstOrDefault();
			var addedUser = (from users in DAO.GetUserByUserID( reviewUserId ) select users).FirstOrDefault();

			string roleName = String.Empty;
			if (asReviewer) {
				roleName = "Reviewer";
			} else {
				roleName = "Participant";
			}

			if (addedUser.EnableJoinMail == true) {
				System.Net.Mail.SmtpClient client = new System.Net.Mail.SmtpClient( ConfigurationManager.AppSettings["SMTPServer"] );
				client.Send( ConfigurationManager.AppSettings["SendEmailFromAddress"], addedUser.ReviewUserEmail,
					// subject
							"CodeDemon - CR #" + review.ReviewID + " (" + review.StatusName + ") Added You as a " + roleName,
					//body
							"The CodeDemon review, CR #" + review.ReviewID + " which is currently in the status " + review.StatusName + " has added you as a "
							+ roleName + "." + Environment.NewLine + Environment.NewLine +
							"by user " + CurrentReviewUserEmail + " at " + DateTime.Now + Environment.NewLine + Environment.NewLine +
							ConfigurationManager.AppSettings["CodeDemonReviewLookupURL"] + reviewId );
			}
			if (reviewOwner.EnableJoinMail == true)
			{
				System.Net.Mail.SmtpClient client = new System.Net.Mail.SmtpClient(ConfigurationManager.AppSettings["SMTPServer"]);
				client.Send(ConfigurationManager.AppSettings["SendEmailFromAddress"], reviewOwner.ReviewUserEmail,
					// subject
							"CodeDemon - CR #" + review.ReviewID + " (" + review.StatusName + ") Added " + addedUser.RealName + " as a " + roleName,
					//body
							"The CodeDemon review, CR #" + review.ReviewID + " which is currently in the status " + review.StatusName + " has added " + addedUser.ReviewUserEmail + " as a "
							+ roleName + "." + Environment.NewLine + Environment.NewLine +
							"by user " + CurrentReviewUserEmail + " at " + DateTime.Now + Environment.NewLine + Environment.NewLine +
							ConfigurationManager.AppSettings["CodeDemonReviewLookupURL"] + reviewId);
			}

			foreach (var part in partList) {
				if (part.EnableJoinMail == true)
				{
					System.Net.Mail.SmtpClient client = new System.Net.Mail.SmtpClient(ConfigurationManager.AppSettings["SMTPServer"]);
					client.Send(ConfigurationManager.AppSettings["SendEmailFromAddress"], part.ReviewUserEmail,
						// subject
								"CodeDemon - CR #" + review.ReviewID + " (" + review.StatusName + ") Added " + addedUser.RealName + " as a " + roleName,
						//body
								"The CodeDemon review, CR #" + review.ReviewID + " which is currently in the status " + review.StatusName + " has added " + addedUser.RealName + " as a "
								+ roleName + "." + Environment.NewLine + Environment.NewLine +
								"by user " + CurrentReviewUserEmail + " at " + DateTime.Now + Environment.NewLine + Environment.NewLine +
								ConfigurationManager.AppSettings["CodeDemonReviewLookupURL"] + reviewId);
				}
			}
		}

		public void SendCommentAlert(int reviewId, int reviewUserId, string commentText, string commentSev, string commentPri)
		{
			var review = (from reviews in DAO.GetReviewsById(reviewId) select reviews).FirstOrDefault();
			var partList = from parts in DAO.GetReviewParticipantsByReviewID(reviewId) where parts.EnableDeltaStatusMail == true select parts;
			var reviewOwner = (from users in DAO.GetUserByUserID(review.ReviewOwnerID) select users).FirstOrDefault();

			if (reviewOwner.EnableCommentMail == true)
			{
				System.Net.Mail.SmtpClient client = new System.Net.Mail.SmtpClient(ConfigurationManager.AppSettings["SMTPServer"]);
				client.Send(ConfigurationManager.AppSettings["SendEmailFromAddress"], reviewOwner.ReviewUserEmail,
					// subject
							"CodeDemon - CR #" + review.ReviewID + "New " + commentSev + " Comment, PRI: " + commentPri,
					//body
							"The CodeDemon review, CR #" + review.ReviewID + " has a new comment "
							+ Environment.NewLine + Environment.NewLine +
							"by user " + CurrentReviewUserEmail + " at " + DateTime.Now + Environment.NewLine + Environment.NewLine +
							ConfigurationManager.AppSettings["CodeDemonReviewLookupURL"] + reviewId
							+ Environment.NewLine + Environment.NewLine +
							"Comment Text:" + Environment.NewLine + commentText
							);
			}

			foreach (var part in partList)
			{
				if (part.EnableCommentMail == true)
				{

					System.Net.Mail.SmtpClient client = new System.Net.Mail.SmtpClient(ConfigurationManager.AppSettings["SMTPServer"]);
					client.Send(ConfigurationManager.AppSettings["SendEmailFromAddress"], part.ReviewUserEmail,
						// subject
								"CodeDemon - CR #" + review.ReviewID + "New " + commentSev + " Comment, PRI: " + commentPri,
						//body
								"The CodeDemon review, CR #" + review.ReviewID + " has a new comment "
								+ Environment.NewLine + Environment.NewLine +
								"by user " + CurrentReviewUserEmail + " at " + DateTime.Now + Environment.NewLine + Environment.NewLine +
								ConfigurationManager.AppSettings["CodeDemonReviewLookupURL"] + reviewId
								+ Environment.NewLine + Environment.NewLine +
								"Comment Text:" + Environment.NewLine + commentText
								);
				} 
			}
			this.CommentHook(reviewId, review.DefectNumber.Value, commentText, commentSev.ToString(), CurrentReviewUserEmail, commentPri);
		}

		public void SendCommentFileAlert(int reviewId, int reviewFileId, int reviewUserId, int reviewCommentId, string commentText, string commentSev, string commentPri)
		{
			var review = (from reviews in DAO.GetReviewsById(reviewId) select reviews).FirstOrDefault();
			var partList = from parts in DAO.GetReviewParticipantsByReviewID(reviewId) where parts.EnableDeltaStatusMail == true select parts;
			var reviewOwner = (from users in DAO.GetUserByUserID(review.ReviewOwnerID) select users).FirstOrDefault();

			if (reviewOwner.EnableCommentMail == true)
			{
				System.Net.Mail.SmtpClient client = new System.Net.Mail.SmtpClient(ConfigurationManager.AppSettings["SMTPServer"]);
				client.Send(ConfigurationManager.AppSettings["SendEmailFromAddress"], reviewOwner.ReviewUserEmail,
					// subject
							"CodeDemon - CR #" + review.ReviewID + "New " + commentSev + " Comment, PRI: " + commentPri,
					//body
							"The CodeDemon review, CR #" + review.ReviewID + " has a new comment "
							+ Environment.NewLine + Environment.NewLine +
							"by user " + CurrentReviewUserEmail + " at " + DateTime.Now + Environment.NewLine + Environment.NewLine +
							ConfigurationManager.AppSettings["CodeDemonReviewFileLookupURL"] + reviewFileId + '#' + reviewCommentId
							+ Environment.NewLine + Environment.NewLine +
							"Comment Text:" + Environment.NewLine + commentText
							);
			}

			foreach (var part in partList)
			{
				if (part.EnableCommentMail == true)
				{

					System.Net.Mail.SmtpClient client = new System.Net.Mail.SmtpClient(ConfigurationManager.AppSettings["SMTPServer"]);
					client.Send(ConfigurationManager.AppSettings["SendEmailFromAddress"], part.ReviewUserEmail,
						// subject
								"CodeDemon - CR #" + review.ReviewID + "New " + commentSev + " Comment, PRI: " + commentPri,
						//body
								"The CodeDemon review, CR #" + review.ReviewID + " has a new comment "
								+ Environment.NewLine + Environment.NewLine +
								"by user " + CurrentReviewUserEmail + " at " + DateTime.Now + Environment.NewLine + Environment.NewLine +
								ConfigurationManager.AppSettings["CodeDemonReviewFileLookupURL"] + reviewFileId + '#' + reviewCommentId
								+ Environment.NewLine + Environment.NewLine +
								"Comment Text:" + Environment.NewLine + commentText
								);
				}
			}
			this.CommentHook(reviewId, review.DefectNumber.Value, commentText, commentSev.ToString(), CurrentReviewUserEmail, commentPri);
		}

		public void SendStatusAlert( int reviewId, string newStatusName, bool isClosed, bool isApproved ) {

			if (newStatusName == "INCOMPLETE") {
				// no one cares!
				return;
			}
			var review = (from reviews in DAO.GetReviewsById(reviewId) select reviews).FirstOrDefault();
			var partList = from parts in DAO.GetReviewParticipantsByReviewID( reviewId) where parts.EnableDeltaStatusMail == true select parts;
			var reviewOwner = (from users in DAO.GetUserByUserID(review.ReviewOwnerID) select users).FirstOrDefault();

			if (reviewOwner.EnableDeltaStatusMail == true)
			{
				System.Net.Mail.SmtpClient client = new System.Net.Mail.SmtpClient(ConfigurationManager.AppSettings["SMTPServer"]);
				client.Send(ConfigurationManager.AppSettings["SendEmailFromAddress"], reviewOwner.ReviewUserEmail,
					// subject
							"CodeDemon - CR #" + review.ReviewID + " now in status " + newStatusName,
					//body
							"The CodeDemon review, CR #" + review.ReviewID + " has been changed to status " + newStatusName + "."
							+ Environment.NewLine + Environment.NewLine +
							"by user " + CurrentReviewUserEmail + " at " + DateTime.Now + Environment.NewLine + Environment.NewLine +
							ConfigurationManager.AppSettings["CodeDemonReviewLookupURL"] + reviewId);
			}

			foreach( var part in partList ) {
					System.Net.Mail.SmtpClient client = new System.Net.Mail.SmtpClient( ConfigurationManager.AppSettings["SMTPServer"] );
					client.Send(ConfigurationManager.AppSettings["SendEmailFromAddress"],part.ReviewUserEmail,
							// subject
								"CodeDemon - CR #" + review.ReviewID + " now in status " + newStatusName,
							//body
								"The CodeDemon review, CR #" + review.ReviewID + " has been changed to status " + newStatusName + "." 
								+ Environment.NewLine + Environment.NewLine +
								"by user " + CurrentReviewUserEmail + " at " + DateTime.Now + Environment.NewLine + Environment.NewLine +
								ConfigurationManager.AppSettings["CodeDemonReviewLookupURL"] + reviewId);
				}

			if (newStatusName != "NEW")
			{
				this.StatusHook(reviewId, review.DefectNumber.Value, newStatusName);
			}
		}


		#endregion Mail & Alerting Methods

		#region Hook Executors

		public void StatusHook(int reviewID, int defectID, string newStatus)
		{
			// StatusHook.pl review_id bug_id new_status CodeDemonReviewLookupURL
			//
			//
			//
			//Code Review Status Changed to "APPROVED"
			//http://THIS_SERVER/codestriker/codestriker.pl?topic=5988769&amp;action=view
			//"APPROVED" by vinit.mishra@standardregister.com
			//"APPROVED" by cory.trese@standardregister.com

			Guid myGuide = System.Guid.NewGuid();
			string ApplicationFilePath = System.Web.Hosting.HostingEnvironment.MapPath(@"~/App_Data");
			string filename = System.IO.Path.Combine(ApplicationFilePath, myGuide.ToString() + ".xml");

			XmlTextWriter xmlWriter = new XmlTextWriter(filename, System.Text.Encoding.UTF8);
			xmlWriter.Formatting = Formatting.Indented;
			xmlWriter.WriteProcessingInstruction("xml", "version='1.0' encoding='UTF-8'");
			xmlWriter.WriteStartElement("codereview_status");
			
			xmlWriter.WriteStartElement("review_status");
			xmlWriter.WriteString(newStatus);
			xmlWriter.WriteEndElement();

			var review = (from reviews in DAO.GetReviewsById(reviewID) select reviews).FirstOrDefault();
			var partList = from parts in DAO.GetReviewParticipantsByReviewID(reviewID) where parts.ParticipantIsReviewer == true select parts;
			foreach (var part in partList)
			{
				xmlWriter.WriteStartElement("reviewer");
				xmlWriter.WriteAttributeString("email", part.ReviewUserEmail);
				xmlWriter.WriteAttributeString("status", part.StatusName);
				xmlWriter.WriteEndElement();
			}

			xmlWriter.WriteStartElement("review_url");
			xmlWriter.WriteString(ConfigurationManager.AppSettings["CodeDemonReviewLookupURL"] + reviewID.ToString());
			xmlWriter.WriteEndElement();

			xmlWriter.WriteStartElement("review_title");
			xmlWriter.WriteString(review.Title);
			xmlWriter.WriteEndElement();

			xmlWriter.WriteStartElement("defect_id");
			xmlWriter.WriteString(defectID.ToString());
			xmlWriter.WriteEndElement();
			xmlWriter.Close();

			// <codereview_status>
			//		<review_status />
			//		<reviewer email="" status="" />
			//		<review_url />
			//		<defect_id />
			//		<review_title />
			// </codereview_status>

			using (Process p2 = new Process())
			{
				p2.StartInfo.UseShellExecute = false;
				p2.StartInfo.CreateNoWindow = true;
				p2.StartInfo.FileName = ConfigurationManager.AppSettings["StatusHookBatch"].ToString();
				p2.StartInfo.Arguments = filename;
				p2.Start();
				p2.WaitForExit();
				File.Delete(filename);
			}
		}

		public void CreateHook( int reviewID, int defectID )
		{
			// CreateHook review_id bug_id owner_email CodeDemonReviewLookupURL
			//
			//
			//
			// New Code Review created.
			// http://THIS_SERVER/codestriker/codestriker.pl?topic=5988769&amp;action=view
			// Author: jeffrey.williams@standardregister.com
			// Reviewer(s): vinit.mishra@standardregister.com, cory.trese@standardregister.com
			// Auxillery User(s): cory.trese@standardregister.com
			// Title: My Review Title
			//
			// Description:
			// Changed the ApprovalHeader to include Home and Sign Off links if a 
			// user enters approvals from the website (as opposed to from a link in 
			// an email). Email users will still see only help and view orders. 

			Guid myGuide = System.Guid.NewGuid();
			string ApplicationFilePath = System.Web.Hosting.HostingEnvironment.MapPath(@"~/App_Data");
			string filename = System.IO.Path.Combine(ApplicationFilePath, myGuide.ToString() + ".xml");

			XmlTextWriter xmlWriter = new XmlTextWriter(filename, System.Text.Encoding.UTF8);
			xmlWriter.Formatting = Formatting.Indented;
			xmlWriter.WriteProcessingInstruction("xml", "version='1.0' encoding='UTF-8'");
			xmlWriter.WriteStartElement("codereview");


			var review = (from reviews in DAO.GetReviewsById(reviewID) select reviews).FirstOrDefault();
			var partList = from parts in DAO.GetReviewParticipantsByReviewID(reviewID) select parts;
			foreach (var part in partList)
			{
				if (part.ParticipantIsReviewer == true)
				{
					xmlWriter.WriteStartElement("reviewer");
					xmlWriter.WriteAttributeString("email", part.ReviewUserEmail);
					xmlWriter.WriteEndElement();
				}
				else
				{
					xmlWriter.WriteStartElement("aux_user");
					xmlWriter.WriteAttributeString("email", part.ReviewUserEmail);
					xmlWriter.WriteEndElement();
				}
			}

			xmlWriter.WriteStartElement("author");
			var author = (from reviews in DAO.GetUserByUserID(review.ReviewOwnerID) select reviews).FirstOrDefault();
			xmlWriter.WriteString(author.ReviewUserEmail);
			xmlWriter.WriteEndElement();

			xmlWriter.WriteStartElement("review_url");
			xmlWriter.WriteString(ConfigurationManager.AppSettings["CodeDemonReviewLookupURL"] + reviewID.ToString());
			xmlWriter.WriteEndElement();

			xmlWriter.WriteStartElement("review_title");
			xmlWriter.WriteString(review.Title);
			xmlWriter.WriteEndElement();

			xmlWriter.WriteStartElement("defect_id");
			xmlWriter.WriteString(defectID.ToString());
			xmlWriter.WriteEndElement();

			xmlWriter.WriteStartElement("review_title");
			xmlWriter.WriteString(review.Title);
			xmlWriter.WriteEndElement();

			xmlWriter.WriteStartElement("description");
			xmlWriter.WriteString(review.Description);
			xmlWriter.WriteEndElement();

			xmlWriter.Close();

			//
			// <codereview>
			//		<author />       *
			//		<reviewer />     *
			//		<aux_user />     *
			//		<review_title /> *
			//		<description />  *
			//		<review_url />   *
			//		<defect_id />    *
			// </codereview>
			using (Process p2 = new Process())
			{
				p2.StartInfo.UseShellExecute = false;
				p2.StartInfo.CreateNoWindow = true;
				p2.StartInfo.FileName = ConfigurationManager.AppSettings["CreateHookBatch"].ToString();
				p2.StartInfo.Arguments = filename;
				p2.Start();
				p2.WaitForExit();
				File.Delete(filename);
			}

		}

		public void CommentHook( int reviewID, int defectID, string commentText, string commentSev, string commentAuthor, string commentPri ) 
		{
			// CommentHook review_id bug_id comment_text comment_sev comment_author CodeDemonReviewLookupURL
			//
			// New Code Review Comment Added.
			// http://THIS_SERVER/codestriker/codestriker.pl?topic=5988769&amp;action=view
			// Author: jeffrey.williams@standardregister.com
			// Severity: MAJOR
			// Priority: 4
			//
			// Comment:
			// This code is shit, please try again.
			//

			Guid myGuide = System.Guid.NewGuid();
			string ApplicationFilePath = System.Web.Hosting.HostingEnvironment.MapPath(@"~/App_Data");
			string filename = System.IO.Path.Combine(ApplicationFilePath, myGuide.ToString() + ".xml");

			XmlTextWriter xmlWriter = new XmlTextWriter(filename, System.Text.Encoding.UTF8);
			xmlWriter.Formatting = Formatting.Indented;
			xmlWriter.WriteProcessingInstruction("xml", "version='1.0' encoding='UTF-8'");
			xmlWriter.WriteStartElement("codereview");

			var review = (from reviews in DAO.GetReviewsById(reviewID) select reviews).FirstOrDefault();

			xmlWriter.WriteStartElement("user");
			xmlWriter.WriteString(commentAuthor);
			xmlWriter.WriteEndElement();

			xmlWriter.WriteStartElement("comment_text");
			xmlWriter.WriteString(commentText);
			xmlWriter.WriteEndElement();

			xmlWriter.WriteStartElement("severity");
			xmlWriter.WriteString(commentSev);
			xmlWriter.WriteEndElement();

			xmlWriter.WriteStartElement("priority");
			xmlWriter.WriteString(commentPri);
			xmlWriter.WriteEndElement();

			xmlWriter.WriteStartElement("review_url");
			xmlWriter.WriteString(ConfigurationManager.AppSettings["CodeDemonReviewLookupURL"] + reviewID.ToString());
			xmlWriter.WriteEndElement();

			xmlWriter.WriteStartElement("review_title");
			xmlWriter.WriteString(review.Title);
			xmlWriter.WriteEndElement();

			xmlWriter.WriteStartElement("defect_id");
			xmlWriter.WriteString(defectID.ToString());
			xmlWriter.WriteEndElement();
			xmlWriter.Close();

			// <codereview>
			//		<user />
			//		<comment_text />
			//		<severity />
			//		<priority />
			//		<review_url />
			//		<defect_id />
			//		<review_title />
			// </codereview>

			using (Process p2 = new Process())
			{
				p2.StartInfo.UseShellExecute = false;
				p2.StartInfo.CreateNoWindow = true;
				p2.StartInfo.FileName = ConfigurationManager.AppSettings["CommentHookBatch"].ToString();
				p2.StartInfo.Arguments = filename;
				p2.Start();
				p2.WaitForExit();
				File.Delete(filename);
			}
		}

		#endregion Hooks

	}
}

